package com.wpml.designmode;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description 责任链模式demo
 * @Date 2021-08-17
 * @Author wangpei
 **/

class Request {
    String str = "";
}

class Response {
    String str = "";
}

public class ResponsibilityChainDemo {
    public static void main(String[] args) {

        FilterChain fc = new FilterChain();

        fc.addFilter(new Filter_one());
        fc.addFilter(new Filter_two());
        fc.addFilter(new Filter_one());
        fc.addFilter(new Filter_two());
        Request request = new Request();
        Response response = new Response();
        fc.doFilter(request, response);

        System.out.println("request : " + request.str);
        System.out.println("response : " + response.str);
    }
}

interface Filter {
    void doFilter(Request request, Response response, FilterChain chain);
}

class FilterChain {

    FilterNode firstNode;
    FilterNode nextNode;
    volatile AtomicInteger size = new AtomicInteger(0);

    List<Filter> list = new LinkedList<>();

    void addFilter(Filter filter) {

        /*if (firstNode == null) {
            firstNode = new FilterNode(filter);
        } else {
            firstNode.next = new FilterNode(filter);
        }*/

        list.add(filter);

    }

    public void doFilter(Request request, Response response){
        /*Filter execFilter;
        if (firstNode != null) {
            execFilter = firstNode.first;
            firstNode = firstNode.next;
            execFilter.doFilter(request, response, this);
        }*/

//        System.out.println(size.getAndIncrement());

        for (int i = size.get(); i < list.size(); i++) {
            if (size.get() == list.size()) return;
            size.incrementAndGet();
            list.get(i).doFilter(request, response, this);
        }
    }
}

class FilterNode{
    Filter first;
    FilterNode next;

    FilterNode(Filter current) {
        first = current;
    }
}

class Filter_one implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        request.str += " request filter_one ";
        chain.doFilter(request,response);
        response.str += " response filter_one ";
    }
}

class Filter_two implements Filter {
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        request.str += " request filter_two ";
        chain.doFilter(request,response);
        response.str += " response filter_two ";

    }
}


